{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Clustering.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_lhcu-eFro6f",
        "colab_type": "text"
      },
      "source": [
        "# 聚类方法"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hGPg5M7wsOQY",
        "colab_type": "text"
      },
      "source": [
        "### 层次聚类 \n",
        "\n",
        "1. **聚合**（自下而上）：聚合法开始将每个样本各自分裂到一个类，之后将相距最近的两类合并，建立一个新的类，重复次操作知道满足停止条件，得到层次化的类别。\n",
        "\n",
        "2. **分裂**（自上而下）： 分裂法开始将所有样本分到一个类，之后将已有类中相距最远的样本分到两个新的类，重复此操作直到满足停止条件，得到层次化的类别。\n",
        "\n",
        "\n",
        "### k均值聚类\n",
        "\n",
        "k均值聚类是基于中心的聚类方法，通过迭代，将样本分到k个类中，使得每个样本与其所属类的中心或均值最近，得到k个平坦的，非层次化的类别，构成对空间的划分。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "qAlQYJ2Srd2_",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import math\n",
        "import random\n",
        "import numpy as np\n",
        "from sklearn import datasets,cluster\n",
        "import matplotlib.pyplot as plt"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "M_XOaWU5xpjI",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "iris = datasets.load_iris()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_swSYxCr0RzU",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 143
        },
        "outputId": "88d09d3b-7700-4af5-e3b6-4d7735a3dd75"
      },
      "source": [
        "gt = iris['target'];gt"
      ],
      "execution_count": 68,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
              "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
              "       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
              "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
              "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
              "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
              "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 68
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UoIRpftd9Uh2",
        "colab_type": "text"
      },
      "source": [
        "3类"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "pI6cS2sjy3Sz",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "outputId": "3d9d01de-31b4-4eea-989c-b0a986a77af5"
      },
      "source": [
        "iris['data'][:,:2].shape"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(150, 2)"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 11
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "YwIVX5j81348",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "data = iris['data'][:,:2]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "h-wEZbDR03E_",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "x = data[:,0]\n",
        "y = data[:,1]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bW_lxjVdy4rW",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 269
        },
        "outputId": "ded2fc31-a69a-4e40-b0d4-350b995488ce"
      },
      "source": [
        "plt.scatter(x, y, color='green')\n",
        "plt.xlim(4, 8)\n",
        "plt.ylim(1, 5)\n",
        "plt.show()"
      ],
      "execution_count": 25,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nrkJggg==\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WkcMa9cs2onL",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# 定义聚类数的节点\n",
        "\n",
        "class ClusterNode:\n",
        "    def __init__(self, vec, left=None, right=None, distance=-1, id=None, count=1):\n",
        "        \"\"\"\n",
        "        :param vec: 保存两个数据聚类后形成新的中心\n",
        "        :param left: 左节点\n",
        "        :param right:  右节点\n",
        "        :param distance: 两个节点的距离\n",
        "        :param id: 用来标记哪些节点是计算过的\n",
        "        :param count: 这个节点的叶子节点个数\n",
        "        \"\"\"\n",
        "        self.vec = vec\n",
        "        self.left = left\n",
        "        self.right = right\n",
        "        self.distance = distance\n",
        "        self.id = id\n",
        "        self.count = count"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_M1vGW8s5ycx",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def euler_distance(point1: np.ndarray, point2: list) -> float:\n",
        "    \"\"\"\n",
        "    计算两点之间的欧拉距离，支持多维\n",
        "    \"\"\"\n",
        "    distance = 0.0\n",
        "    for a, b in zip(point1, point2):\n",
        "        distance += math.pow(a - b, 2)\n",
        "    return math.sqrt(distance)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "udgrrhsn19X1",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# 层次聚类（聚合法）\n",
        "\n",
        "class Hierarchical:\n",
        "    def __init__(self, k):\n",
        "        self.k = k\n",
        "        self.labels = None\n",
        "        \n",
        "    def fit(self, x):\n",
        "        nodes = [ClusterNode(vec=v, id=i) for i, v in enumerate(x)]\n",
        "        distances = {}\n",
        "        point_num, feature_num = x.shape\n",
        "        self.labels = [-1] * point_num\n",
        "        currentclustid = -1\n",
        "        while(len(nodes)) > self.k:\n",
        "            min_dist = math.inf\n",
        "            nodes_len = len(nodes)\n",
        "            closest_part = None\n",
        "            for i in range(nodes_len - 1):\n",
        "                for j in range(i+1, nodes_len):\n",
        "                    d_key = (nodes[i].id, nodes[j].id)\n",
        "                    if d_key not in distances:\n",
        "                        distances[d_key] = euler_distance(nodes[i].vec, nodes[j].vec)\n",
        "                    d = distances[d_key]\n",
        "                    if d < min_dist:\n",
        "                        min_dist = d\n",
        "                        closest_part = (i, j)\n",
        "                        \n",
        "            part1, part2 = closest_part\n",
        "            node1, node2 = nodes[part1], nodes[part2]\n",
        "            new_vec = [ (node1.vec[i] * node1.count + node2.vec[i] * node2.count ) / (node1.count + node2.count)\n",
        "                        for i in range(feature_num)]\n",
        "            new_node = ClusterNode(vec=new_vec,\n",
        "                                   left=node1,\n",
        "                                   right=node2,\n",
        "                                   distance=min_dist,\n",
        "                                   id=currentclustid,\n",
        "                                   count=node1.count + node2.count)\n",
        "            currentclustid -= 1\n",
        "            del nodes[part2], nodes[part1]\n",
        "            nodes.append(new_node)\n",
        "            \n",
        "        self.nodes = nodes\n",
        "        self.calc_label()\n",
        "        \n",
        "    def calc_label(self):\n",
        "        \"\"\"\n",
        "        调取聚类的结果\n",
        "        \"\"\"\n",
        "        for i, node in enumerate(self.nodes):\n",
        "            # 将节点的所有叶子节点都分类\n",
        "            self.leaf_traversal(node, i)\n",
        "\n",
        "    def leaf_traversal(self, node: ClusterNode, label):\n",
        "        \"\"\"\n",
        "        递归遍历叶子节点\n",
        "        \"\"\"\n",
        "        if node.left == None and node.right == None:\n",
        "            self.labels[node.id] = label\n",
        "        if node.left:\n",
        "            self.leaf_traversal(node.left, label)\n",
        "        if node.right:\n",
        "            self.leaf_traversal(node.right, label)\n",
        "            \n",
        "# https://zhuanlan.zhihu.com/p/32438294"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "LwD9Iots6871",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 107
        },
        "outputId": "be527c5e-3be7-40ee-c361-37a0ab57440b"
      },
      "source": [
        "my = Hierarchical(3)\n",
        "my.fit(data)\n",
        "labels = np.array(my.labels)\n",
        "print(labels)"
      ],
      "execution_count": 49,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n",
            " 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 2 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0\n",
            " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 2 0 0 0 1 0 0 1 2 1 0 1 0\n",
            " 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0\n",
            " 0 0]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "yJN0NPWn8F6K",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 281
        },
        "outputId": "f8238840-dd5e-45b3-e5b2-b4fa3836f7bb"
      },
      "source": [
        "# visualize result\n",
        "\n",
        "cat1 = data[np.where(labels==0)]\n",
        "cat2 = data[np.where(labels==1)]\n",
        "cat3 = data[np.where(labels==2)]\n",
        "\n",
        "plt.scatter(cat1[:,0], cat1[:,1], color='green')\n",
        "plt.scatter(cat2[:,0], cat2[:,1], color='red')\n",
        "plt.scatter(cat3[:,0], cat3[:,1], color='blue')\n",
        "plt.title('Hierarchical clustering with k=3')\n",
        "plt.xlim(4, 8)\n",
        "plt.ylim(1, 5)\n",
        "plt.show()"
      ],
      "execution_count": 63,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nSUVORK5CYII=\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "7xilKyap8ghX",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 107
        },
        "outputId": "0a58379a-679a-4d0b-fe13-241585f60d81"
      },
      "source": [
        "sk = cluster.AgglomerativeClustering(3)\n",
        "sk.fit(data)\n",
        "labels_ = sk.labels_\n",
        "print(labels_)"
      ],
      "execution_count": 66,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n",
            " 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 2 0 2 0 1 0 1 1 0 2 0 2 0 2 2 2 2 0 0 2 0\n",
            " 0 0 0 0 0 2 2 2 2 0 2 0 0 2 2 2 2 0 2 1 2 2 2 0 1 2 0 2 0 0 0 0 1 0 0 0 0\n",
            " 0 0 2 2 0 0 0 0 2 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 2 0\n",
            " 0 0]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "hlFZeDdW9Bzr",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 281
        },
        "outputId": "7a837637-70e6-4c40-b6f2-c6a651fc4cae"
      },
      "source": [
        "# visualize result of sklearn\n",
        "\n",
        "cat1_ = data[np.where(labels_==0)]\n",
        "cat2_ = data[np.where(labels_==1)]\n",
        "cat3_ = data[np.where(labels_==2)]\n",
        "\n",
        "plt.scatter(cat1_[:,0], cat1_[:,1], color='green')\n",
        "plt.scatter(cat2_[:,0], cat2_[:,1], color='red')\n",
        "plt.scatter(cat3_[:,0], cat3_[:,1], color='blue')\n",
        "plt.title('Hierarchical clustering with k=3')\n",
        "plt.xlim(4, 8)\n",
        "plt.ylim(1, 5)\n",
        "plt.show()"
      ],
      "execution_count": 67,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n8f8BxfmbJ1GlvqAAAAAASUVORK5CYII=\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "La_XZDI5_Bng",
        "colab_type": "text"
      },
      "source": [
        "---------------------------------------------------------------------------------------------------------------------------------"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "fNl9AY6vAFJG",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# kmeans\n",
        "\n",
        "class MyKmeans:\n",
        "    def __init__(self, k, n=20):\n",
        "        self.k = k\n",
        "        self.n = n\n",
        "        \n",
        "    def fit(self, x, centers=None):\n",
        "        # 第一步，随机选择 K 个点, 或者指定\n",
        "        if centers is None:\n",
        "            idx = np.random.randint(low=0, high=len(x), size=self.k)\n",
        "            centers = x[idx]\n",
        "        #print(centers)\n",
        "        \n",
        "        inters = 0\n",
        "        while inters < self.n:\n",
        "            #print(inters)\n",
        "            #print(centers)\n",
        "            points_set = {key: [] for key in range(self.k)}\n",
        "\n",
        "            # 第二步，遍历所有点 P，将 P 放入最近的聚类中心的集合中\n",
        "            for p in x:\n",
        "                nearest_index = np.argmin(np.sum((centers - p) ** 2, axis=1) ** 0.5)\n",
        "                points_set[nearest_index].append(p)\n",
        "\n",
        "            # 第三步，遍历每一个点集，计算新的聚类中心\n",
        "            for i_k in range(self.k):\n",
        "                centers[i_k] = sum(points_set[i_k])/len(points_set[i_k])\n",
        "                \n",
        "            inters += 1\n",
        "\n",
        "        \n",
        "            \n",
        "        return points_set, centers\n",
        "        "
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "SyLthTXfBfnV",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "m = MyKmeans(3)\n",
        "points_set, centers = m.fit(data)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "VE2ryNB-O_Zt",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 71
        },
        "outputId": "55a70e58-fccd-4001-c67c-964ede3a8550"
      },
      "source": [
        "centers"
      ],
      "execution_count": 205,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[5.02173913, 3.44782609],\n",
              "       [5.77358491, 2.69245283],\n",
              "       [6.81276596, 3.07446809]])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 205
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "M26gflVYDzY4",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 281
        },
        "outputId": "abb1b7b1-df4f-4fa1-9a24-1dc722112c2c"
      },
      "source": [
        "# visualize result\n",
        "\n",
        "cat1 = np.asarray(points_set[0])\n",
        "cat2 = np.asarray(points_set[1])\n",
        "cat3 = np.asarray(points_set[2])\n",
        "\n",
        "for ix, p in enumerate(centers):\n",
        "    plt.scatter(p[0], p[1], color='C{}'.format(ix), marker='^', edgecolor='black', s=256)\n",
        "        \n",
        "plt.scatter(cat1_[:,0], cat1_[:,1], color='green')\n",
        "plt.scatter(cat2_[:,0], cat2_[:,1], color='red')\n",
        "plt.scatter(cat3_[:,0], cat3_[:,1], color='blue')\n",
        "plt.title('Hierarchical clustering with k=3')\n",
        "plt.xlim(4, 8)\n",
        "plt.ylim(1, 5)\n",
        "plt.show()"
      ],
      "execution_count": 206,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nAAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "HiFFoBdWN4fW",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# using sklearn\n",
        "\n",
        "kmeans = KMeans(n_clusters=3, max_iter=100).fit(data)\n",
        "gt_labels__ = kmeans.labels_\n",
        "centers__ = kmeans.cluster_centers_"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "LgKRAwmxObYS",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 143
        },
        "outputId": "032bcef5-ba68-4707-fbb0-f7a225ee968f"
      },
      "source": [
        "gt_labels__"
      ],
      "execution_count": 163,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([1, 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
              "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
              "       2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1,\n",
              "       0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,\n",
              "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1,\n",
              "       1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,\n",
              "       1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0], dtype=int32)"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 163
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "A0iu18HPOcrH",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 71
        },
        "outputId": "5794f33c-4ebd-47dc-d351-05f44c17343d"
      },
      "source": [
        "centers__"
      ],
      "execution_count": 200,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[5.77358491, 2.69245283],\n",
              "       [5.02173913, 3.44782609],\n",
              "       [6.81276596, 3.07446809]])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 200
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wEfO5JVjOC5p",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 281
        },
        "outputId": "a6386044-2c7b-420d-f429-0b4960900f83"
      },
      "source": [
        "# visualize result\n",
        "\n",
        "cat1 = data[gt_labels__ == 0]\n",
        "cat2 = data[gt_labels__ == 1]\n",
        "cat3 = data[gt_labels__ == 2]\n",
        "\n",
        "for ix, p in enumerate(centers__):\n",
        "    plt.scatter(p[0], p[1], color='C{}'.format(ix), marker='^', edgecolor='black', s=256)\n",
        "        \n",
        "plt.scatter(cat1_[:,0], cat1_[:,1], color='green')\n",
        "plt.scatter(cat2_[:,0], cat2_[:,1], color='red')\n",
        "plt.scatter(cat3_[:,0], cat3_[:,1], color='blue')\n",
        "plt.title('kmeans using sklearn with k=3')\n",
        "plt.xlim(4, 8)\n",
        "plt.ylim(1, 5)\n",
        "plt.show()"
      ],
      "execution_count": 164,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "u5XVOLGBKC4A",
        "colab_type": "text"
      },
      "source": [
        "#### 寻找 K 值"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "uCe9-EHaJrFz",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 281
        },
        "outputId": "4c2fe667-ee92-4909-c582-6605bd862ecc"
      },
      "source": [
        "from sklearn.cluster import KMeans\n",
        "\n",
        "loss = []\n",
        "\n",
        "for i in range(1, 10):\n",
        "    kmeans = KMeans(n_clusters=i, max_iter=100).fit(data)\n",
        "    loss.append(kmeans.inertia_ / len(data) / 3)\n",
        "\n",
        "plt.title('K with loss')\n",
        "plt.plot(range(1, 10), loss)\n",
        "plt.show()"
      ],
      "execution_count": 129,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAEICAYAAACzliQjAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzt3Xt4XPV95/H3VxrdJUu2dRnjCzbY\ngC1BMBZ2TAok4IsoWUgWKJCEQh8aSDb0SZPus5s27aYlu02b9JI0zW6gkCakAQImSXkagsFcTCgG\nLBsDvt+wsXzRzbZs3W/f/WOOzVjI1tiSfEYzn9fzzKM5Z34z84EHPmfO75w5Y+6OiIikh4ywA4iI\nyNmj0hcRSSMqfRGRNKLSFxFJIyp9EZE0otIXEUkjKn0RwMw+a2bPneLxj5tZ3Wm83stm9ocjk05k\n5Kj0Zcwxs11mtihu+TYzO2RmV5/pa7r7z9x9SdxrupnNHG5WkWSj0pcxzczuBH4AXO/uK8POI5Ls\nVPoyZpnZvcDfA0vd/bWTjFlpZjcF9z8WfIK/Pli+1szWBffvMrNXg/uvBE9/28xazezWuNf7EzNr\nMLP9ZvYHCebMMLM/N7PdwXMfMbPi4LFcM/s3M2s2s8NmttrMKuIy7TSzo2b2npl99oz+RYnEUenL\nWPVF4H7gWnevPcW4lcDHg/tXAzuBq+KWP7R34O7HHv+Iuxe6+8+D5ShQDEwG7gZ+YGbjE8h6V3D7\nBHAeUAj8c/DYncFrTgUmAl8AOsysAPgn4Dp3LwKuANYl8F4ip6TSl7FqMfA68O4Q41YSK3eIlf23\n4pYHLf1T6AHud/ced38GaAUuTOB5nwX+wd13unsr8KfAbWYWCV5zIjDT3fvcfY27Hwme1w9UmVme\nu+939w2nkVVkUCp9Gau+CFwAPGRmdopxq4ALgimTS4FHgKlmVgrMB145xXMHanb33rjldmKf2ody\nDrA7bnk3EAEqgJ8Cy4HHzWyfmX3bzLLcvQ24ldgn//1m9mszu+g0sooMSqUvY1U9cC1wJfB/TzbI\n3duBNcCXgfXu3g28BnwV2OHuTWch6z7g3LjlaUAvUB/sNfyVu88hNoXzSeD3g+zL3X0xMAnYDPzL\nWcgqKU6lL2OWu+8jVvw1ZvaPpxi6EriPD6ZyXh6wPJh6YvPvI+Ex4CtmNsPMCoG/Bn7u7r1m9gkz\nu9jMMoEjxKZ7+s2swsxuDOb2u4hNJfWPUB5JYyp9GdPc/X3gGuBmM/vWSYatBIr4YCpn4PJg/hL4\nSXBGze8NM+aPiE3jvAK8B3QCfxQ8FgWWESv8TUG2nxL7f/OrxPYSDhI7/vDFYeYQwfQjKiIi6UOf\n9EVE0ohKX0Qkjaj0RUTSiEpfRCSNRMIOMFBpaalPnz497BgiImPKmjVrmty9bKhxSVf606dPp7b2\nVJdSERGRgcxs99CjNL0jIpJWVPoiImlEpS8ikkZU+iIiaUSlLyKSRlT6IiJpRKUvIpJGUqb0D7d3\n870V29i478jQg0VE0lTSfTnrTJkZ339xG+09vcw5Z1zYcUREklLKfNIvzsviipmlLF9/AP1GgIjI\n4FKm9AFqKqPsam5na31r2FFERJJSSpX+4jkVmMGz6w+EHUVEJCmlVOmXFeVw+bkTeHaDSl9EZDAp\nVfoASyor2LT/CLub28KOIiKSdFKu9JdWRgFYrk/7IiIfknKlP3VCPlWTx2leX0RkEClX+hA7i2ft\n+4epP9IZdhQRkaSSmqVfFZvieU5TPCIiJ0jJ0p9ZXsT5ZQUs31AfdhQRkaSSkqUPsU/7q3Y2c7i9\nO+woIiJJI3VLv3ISff3Oik0NYUcREUkaKVv6VZPHMbkkT2fxiIjESdnSNzOWVFbwyrZG2rp6w44j\nIpIUUrb0IXbqZndvPy9vaQw7iohIUkjp0q+ePoGJBdm6Fo+ISCClSz8zIzbF89LmBrp6+8KOIyIS\nupQufYhdi6e1q5fXtjeHHUVEJHQpX/pXnF9KUU5EZ/GIiJAGpZ8dyeCa2eU8v6me3r7+sOOIiIQq\n5UsfYmfxHGzrZvWuQ2FHEREJVVqU/tUXlpETydA19kUk7aVF6ednR7j6gjKeXX+A/n4PO46ISGgS\nKn0zqzGzLWa23cy+NsjjXzWzjWb2jpm9YGbnxj3WZ2brgtvTIxn+dNRURTlwpJN39raEFUFEJHRD\nlr6ZZQI/AK4D5gC3m9mcAcPeAqrd/RJgGfDtuMc63P3S4HbDCOU+bddeVEEkwzTFIyJpLZFP+vOB\n7e6+0927gceBG+MHuPtL7t4eLL4OTBnZmMNXnJ/FwvMn8uz6A7hrikdE0lMipT8Z2BO3XBesO5m7\ngd/ELeeaWa2ZvW5mnxrsCWZ2TzCmtrFx9K6Ts7QyyntNbWxraB219xARSWYjeiDXzD4HVAPfiVt9\nrrtXA58Bvmtm5w98nrs/6O7V7l5dVlY2kpFOsGROBWboi1oikrYSKf29wNS45SnBuhOY2SLg68AN\n7t51bL277w3+7gReBuYOI++wlI/LZd608Sp9EUlbiZT+amCWmc0ws2zgNuCEs3DMbC7wALHCb4hb\nP97McoL7pcDHgI0jFf5M1FRF2bj/CO83tw89WEQkxQxZ+u7eC9wHLAc2AU+4+wYzu9/Mjp2N8x2g\nEHhywKmZs4FaM3sbeAn4G3cPtfSXVkYBdBaPiKQlS7YzWaqrq722tnZU3+P6f/otuVmZPPXFK0b1\nfUREzhYzWxMcPz2ltPhG7kA1lVHWvn+IhiOdYUcRETmr0rL0l1ZFcYfnNtaHHUVE5KxKy9KfVV7I\neaUFmtcXkbSTlqVvZiytirJqRzOH27vDjiMictakZelDbF6/t995YVPD0INFRFJE2pb+JVOKmVSc\ny7Oa4hGRNJK2pW9mLK2M8srWRtq6esOOIyJyVqRt6UPs27ldvf2s3Dp6F3kTEUkmaV36l0+fwISC\nbJ3FIyJpI61LPzPDWDy7ghc3NdDV2xd2HBGRUZfWpQ+xKZ6jXb28tqM57CgiIqMu7Uv/ipkTKcyJ\nsFyXWxaRNJD2pZ8TyeSai8p5bmM9ff3JdfE5EZGRlvalD7EpnoNt3azedTDsKCIio0qlD1x9QRk5\nkQz9opaIpDyVPlCQE+HKWWU8t+EAyfb7AiIiI0mlH6ipirKvpZN397aEHUVEZNSo9AOLZpeTmWGa\n4hGRlKbSD5TkZ7PwvIk8u15TPCKSulT6cZZWRdnZ1Mb2htawo4iIjAqVfpylcyowQ1M8IpKyVPpx\nysflctm08brGvoikLJX+ADWVUTbsO8Keg+1hRxERGXEq/QGWVkYBdLllEUlJKv0Bpk3MZ/akcSp9\nEUlJKv1B1FRGqd19iIajnWFHEREZUSr9QdRURXGH5zfWhx1FRGREqfQHcUFFITNKC3TqpoikHJX+\nIMyMpZVRVu1opqW9J+w4IiIjJqHSN7MaM9tiZtvN7GuDPP5VM9toZu+Y2Qtmdm7cY3ea2bbgdudI\nhh9NNVVRevudFzZrikdEUseQpW9mmcAPgOuAOcDtZjZnwLC3gGp3vwRYBnw7eO4E4BvAAmA+8A0z\nGz9y8UfPJZOLiY7L1Vk8IpJSEvmkPx/Y7u473b0beBy4MX6Au7/k7se+zfQ6MCW4vxR43t0Puvsh\n4HmgZmSij66MDGNpZQUrtzbS3t0bdhwRkRGRSOlPBvbELdcF607mbuA3p/NcM7vHzGrNrLaxsTGB\nSGfH0qoonT39vLI1eTKJiAzHiB7INbPPAdXAd07nee7+oLtXu3t1WVnZSEYalvnTJzA+P0tn8YhI\nykik9PcCU+OWpwTrTmBmi4CvAze4e9fpPDdZRTIzWDynghc2NdDd2x92HBGRYUuk9FcDs8xshpll\nA7cBT8cPMLO5wAPECr8h7qHlwBIzGx8cwF0SrBszaqqiHO3q5bUdTWFHEREZtiFL3917gfuIlfUm\n4Al332Bm95vZDcGw7wCFwJNmts7Mng6eexD4JrENx2rg/mDdmHHF+aUU5kR0Fo+IpARLtp8GrK6u\n9tra2rBjnOC+R9eyakczb359EZkZFnYcEZEPMbM17l491Dh9IzcBNVVRmtu6WbP7UNhRRESGRaWf\ngI9fWE52JENn8YjImKfST0BhToSrZpWyfMMBkm06TETkdKj0E7S0Msrewx2s33sk7CgiImdMpZ+g\nRbMryMwwnt2wP+woIiJnTKWfoPEF2Xz0vAma1xeRMU2lfxqWVkbZ0djG9oajYUcRETkjKv3TsGRO\nFECf9kVkzFLpn4ZocS5zp5WwfIN+WEVExiaV/mmqqYzy7t4W6g61Dz1YRCTJqPRP09LK2BSPPu2L\nyFik0j9N00sLuChaxHLN64vIGKTSPwM1VVFW7z5I49GuoQeLiCQRlf4ZWFoZxR2e36gpHhEZW1T6\nZ+CiaBHnTsznWV1jX0TGGJX+GTAzaiqjrNrRREtHT9hxREQSptI/Q0urovT0OS9tbhh6sIhIklDp\nn6FLp5RQMS5H384VkTFFpX+GMjKMpZVRXt7aQEd3X9hxREQSotIfhprKKJ09/azc2hh2FBGRhKj0\nh2H+jAmU5GexXGfxiMgYodIfhkhmBotmV7BiUz3dvf1hxxERGZJKf5hqKqMc7exl1c7msKOIiAxJ\npT9MvzOrlPzsTE3xiMiYoNIfptysTD5xUTnPbainr9/DjiMickoq/RFQUxmlqbWLte8fCjuKiMgp\nqfRHwCcuKic7M0Nf1BKRpKfSHwGFORGunFXKs+sP4K4pHhFJXir9EbK0Msrewx1s2Hck7CgiIieV\nUOmbWY2ZbTGz7Wb2tUEev8rM1ppZr5ndPOCxPjNbF9yeHqngyWbRnAoyDE3xiEhSG7L0zSwT+AFw\nHTAHuN3M5gwY9j5wF/DoIC/R4e6XBrcbhpk3aU0oyGbBjIm6xr6IJLVEPunPB7a7+0537wYeB26M\nH+Duu9z9HSCtv5ZaUxVle0Mr2xtaw44iIjKoREp/MrAnbrkuWJeoXDOrNbPXzexTgw0ws3uCMbWN\njWP34mVLKisA9EUtEUlaZ+NA7rnuXg18BviumZ0/cIC7P+ju1e5eXVZWdhYijY5JxXlcOrVEpS8i\nSSuR0t8LTI1bnhKsS4i77w3+7gReBuaeRr4xp6Yqyjt1Lew93BF2FBGRD0mk9FcDs8xshpllA7cB\nCZ2FY2bjzSwnuF8KfAzYeKZhx4KllVEAlussHhFJQkOWvrv3AvcBy4FNwBPuvsHM7jezGwDM7HIz\nqwNuAR4wsw3B02cDtWb2NvAS8DfuntKlP6O0gAsrinQWj4gkpUgig9z9GeCZAev+V9z91cSmfQY+\n7zXg4mFmHHOWVkX5/ovbaGrtorQwJ+w4IiLH6Ru5o6CmMoo7rNhYH3YUEZETqPRHwexJRUybkK8p\nHhFJOir9UWBm1FRF+c/tTRzp7Ak7jojIcSr9UbK0MkpPn/PS5oawo4iIHKfSHyVzp5ZQXpSjC7CJ\nSFJR6Y+SjAxjSWUFL29ppKO7L+w4IiKASn9U1VROoqOnj1e2jd3rCYlIalHpj6IF502gOC9L384V\nkaSh0h9FWZkZLJpdwYpN9fT0pfVVp0UkSaj0R1lNVZQjnb28ur0p7CgiIir90XblrFLKi3L470+8\nzUb9fq6IhEylP8pyszJ57J6Pkh3J4LYHV/HW+4fCjiQiaUylfxacX1bIE/cupCQ/m8899Aav72wO\nO5KIpCmV/lkydUI+T9y7kGhxLnf+6E1e3qJv6orI2afSP4uixbk8ce9Czi8r5POP1OrbuiJy1qn0\nz7KJhTk89vmPUjW5mC89upZfvZXwL0+KiAybSj8ExflZ/PTuBVw+fTxfeWIdj77xftiRRCRNqPRD\nUpgT4cd/MJ+rLyjjz375Lg/9dmfYkUQkDaj0Q5SblckDd8yjpjLK//71Jr7/wjbcPexYIpLCVPoh\ny4lk8s+fmcun507m75/fyt8+u0XFLyKjJqEfRpfRFcnM4O9v+Qh52Zn8cOUOOrp7+cZ/qSQjw8KO\nJiIpRqWfJDIyjP/zqSryszJ56NX3aOvu429vuoRMFb+IjCCVfhIxM75+/WwKciJ874VtdPT08d1b\nLyUrU7NwIjIyVPpJxsz4yuILyM/O5Fu/2UxXTx///JnLyM3KDDuaiKQAfYRMUvdefT7fvLGSFZsa\nuPsnq2nv7g07koikAJV+Ertj4XT+7paPsGpHM7//8Jsc6ewJO5KIjHEq/SR387wpfP/2y1i35zCf\n/Zc3ONjWHXYkERnDVPpjwPWXTOLB35/Hlvqj3PbgKhqOdoYdSUTGKJX+GHHNRRX8+K7LqTvUwe/9\ncBV7D3eEHUlExqCESt/Masxsi5ltN7OvDfL4VWa21sx6zezmAY/daWbbgtudIxU8HV0xs5Sf3j2f\n5rZufu+Hq9jV1BZ2JBEZY4YsfTPLBH4AXAfMAW43szkDhr0P3AU8OuC5E4BvAAuA+cA3zGz88GOn\nr3nnTuCxz3+U9u5ebnlgFVvrj4YdSUTGkEQ+6c8Htrv7TnfvBh4Hbowf4O673P0doH/Ac5cCz7v7\nQXc/BDwP1IxA7rRWNbmYn9+7EIBbH1jF+r0tIScSkbEikdKfDOyJW64L1iUioeea2T1mVmtmtY2N\njQm+dHq7oKKIJ+9dSH52hNsffJ01uw+GHUlExoCkOJDr7g+6e7W7V5eVlYUdZ8yYXlrAE19YyMTC\nbO54+E1e294UdiQRSXKJlP5eYGrc8pRgXSKG81xJwOSSPJ64dyFTxudx149X8+Lm+rAjiUgSS6T0\nVwOzzGyGmWUDtwFPJ/j6y4ElZjY+OIC7JFgnI6h8XC4/v2chF1YUcc8ja/j1O/vDjiQiSWrI0nf3\nXuA+YmW9CXjC3TeY2f1mdgOAmV1uZnXALcADZrYheO5B4JvENhyrgfuDdTLCxhdk87PPL+DSqSX8\n0WNrWbamLuxIIpKELNl+pam6utpra2vDjjFmtXf3cs8ja3h1exPfvLGSOxZODzuSiJwFZrbG3auH\nGpcUB3Jl5ORnR3jozmquvaicv/j3DTz4yo6wI4lIElHpp6DcrEx+eMc8rr9kEn/9zGb+8fmt+t1d\nEQH0IyopKyszg3+6bS55WZl874VttHf38me/Oxsz/fyiSDpT6aewzAzj2zddQkF2Jv/y2/do7+7j\nmzdW6QfXRdKYSj/FZWQYf3lDJXnZEX64cgcd3X18++ZLiOh3d0XSkko/DZgZ/7PmQgpzMvm757bS\n0dPH926bS3ZExS+SbvR/fZowM+67ZhZ/8ck5/Gb9Ae75aS2dPX1hxxKRs0yln2bu/p0Z/PWnL2bl\n1kbu+tc3aWnX7+6KpBNN76ShzyyYRn52Jn/y5Nss+NYKaiqj3FI9lYXnTdRBXpEUp9JPU5+aO5lZ\nFYU8+sb7PP32Pn61bh+TS/K4ad4Ubpk3hakT8sOOKCKjQJdhEDp7+li+4QDL1tTx6vYm3OGj503g\nlnlTue7iKPnZ+mwgkuwSvQyDSl9OsPdwB79YU8eytXXsbm6nMCfC9RdP4pbqKcw7d7y+3CWSpFT6\nMizuzpvvHeTJNXU88+5+2rv7OK+0gJvmTeGmy6YQLc4NO6KIxFHpy4hp6+rl1+/uZ1ltHW/uOkiG\nwZWzyrilegqL51SQE8kMO6JI2lPpy6jY1dTGsjV1PLW2jv0tnRTnZXHjpedwy7ypVE0ep+kfkZCo\n9GVU9fU7/7m9iSfX1LF8wwG6e/u5KFrEzfOm8Om5k5lYmBN2RJG0otKXs6alvYen39nHsto9vF3X\nQiTDuOaicm6pnsrHLywjS9f5ERl1Kn0JxZYDR1m2Zg+/fGsvTa3dlBbm8Om553BL9VQuqCgKO55I\nylLpS6h6+vp5eUsjT9bu4cXNDfT2Ox+ZUszN1VO54SPnUJyXFXZEkZSi0pek0dTaxa/e2suyNXVs\nPnCU7EgGSyuj3DJvCh+bWUqmLv0gMmwqfUk67s76vUd4cs0e/n3dPlo6ephUnMtNl03h5nlTmF5a\nEHZEkTFLpS9JrbOnjxWb6nmyto7fbmuk32H+9AncXD2F6y+eREGOLv0gcjpU+jJmHGjp5Km1dSxb\nU8d7TW3kZ2dy7ewKFs0u5+MXlmv+XyQBKn0Zc9ydNbsP8dTaOp7bUE9zWzeRDGPBeRNYNLuCRbMr\ndPVPkZNQ6cuY1tfvrNtzmOc31rNiUz3bG1oBuChaxKLZFSyeU8HFk4t1/X+RgEpfUsp7TW28sKme\n5zfWs3rXQfodyotyuHZ2BYvnlHPF+aXkZukaQJK+VPqSsg61dfPSlgZWbKpn5ZZG2rr7yMvK5KoL\nSlk0u4JrLirXZSAk7aj0JS109fbx+s6DrAimgfa3dGIG86aNZ9Gc2HGAmeWFYccUGXUqfUk77s6G\nfUeOHwfYsO8IAOeVFhzfAFw2rYSIrgUkKWhES9/MaoDvAZnAQ+7+NwMezwEeAeYBzcCt7r7LzKYD\nm4AtwdDX3f0Lp3ovlb6MlL2HO44fB3h9ZzM9fc74/Cw+cVE5S+ZUcOWsMn0fQFLGiJW+mWUCW4HF\nQB2wGrjd3TfGjflvwCXu/gUzuw34tLvfGpT+f7h7VaLBVfoyGo529vDK1iZWbKrnxc0NtHT0kJ2Z\nwRUzJx4/HVS/BiZj2UiW/kLgL919abD8pwDu/q24McuDMavMLAIcAMqAc1HpS5Lp6eundtchVgR7\nAe8fbAfgkinFxzcAsycV6QdhZEwZydK/Gahx9z8Mlu8AFrj7fXFj1gdj6oLlHcACoBDYQGxP4Qjw\n5+7+20He4x7gHoBp06bN2717d0L/kCLD5e5sb2jlueA4wLo9h3GHySV5LJpdzqI5FSyYMZHsiI4D\nSHJLtPRHe0JzPzDN3ZvNbB7wKzOrdPcj8YPc/UHgQYh90h/lTCLHmRmzKoqYVVHElz4xk4ajnby0\nuYHnNzbw89o9/GTVbopyIlx9YRmL51RQPX0C5xTnai9AxqxESn8vMDVueUqwbrAxdcH0TjHQ7LHd\niC4Ad18T7AFcAGj+RpJSeVEut14+jVsvn0ZHdx+vbm9ixcZ6Xthcz3+8sx+A/OxMZpYXMrOskPPL\nC5lZXsis8kKmTcjXmUGS9BIp/dXALDObQazcbwM+M2DM08CdwCrgZuBFd3czKwMOunufmZ0HzAJ2\njlh6kVGUl53J4jmxSz709ztv1x1mw74jbG9oZUdjK6t2NvOLtz74/JOdmcH00nxmlRcd3xjMLCvk\nvLICfVtYksaQpe/uvWZ2H7Cc2CmbP3L3DWZ2P1Dr7k8DDwM/NbPtwEFiGwaAq4D7zawH6Ae+4O4H\nR+MfRGQ0ZWQYc6eNZ+608SesP9rZw47GNrY3tLKt4Sg7GlrZsK+F36zfT38wUZlhMHVCPjPLCplZ\nEdsQzAw2CkW5uoKonF36cpbIKOjs6eO9ptjGIP72XlMb3X39x8dFx+Ue3wDE3yYWZOu4gZyWZDmQ\nK5KWcrMymT1pHLMnjTthfW9fP3sOdbCt/ijbGz/YGDxZu4e27r7j48bnZx3fAJxfVsisiiJmlhfq\nILIMm0pf5CyKZGYwo7SAGaUFLIlb7+7sb+kMpoliG4IdDa08u/4Ah9p7jo872UHkqRPyydJBZEmA\nSl8kCZgZ55TkcU5JHlddUHbCY82tXbE9grg9g4EHkc2grDCHSSV5nFOcy6TiPM4pif2dVJLLOcV5\nlBXl6EfoRaUvkuwmFuYwsTCHBedNPGF9/EHkPQfb2d/Swf6WTrbWH2Xl1kba46aLACIZRsW4XCYV\n53JOyQcbg+PLxblM0LGElKfSFxmjinKzuHRqCZdOLfnQY+7OkY5e9rV0sL+lg32HO2MbhcOd7Gvp\nYN2ewzy7vvOEg8oAOZEMJhWfuIcQ/3dScR7jciPaMIxhKn2RFGRmFOdnUZyf9aGDycf09zvNbd0n\nbhRaOtl3OPb39R3N1B/toq//xDP8CrIzgz2FD6aSBm4g8rL1vYRkpdIXSVMZGUZZUQ5lRTlcMmXw\nMb19/TS2dp2wp7D3cMfxDcTGfUdoau360PNK8rOYVJxHxbgcJhbkUFqYTWlhDhMLs2PTVQWx5QkF\n2bqu0Vmm0heRk4pkZsQ+yRfnAeMHHdPV20d9S9egU0kNR7vYeuAoTa3dH5pKOqY4L4uJhdmUFhzb\nKBzbQORQWhBsJILHx+Vpamm4VPoiMiw5kUymTcxn2sT8k45xd1q7emlu7aaptYum1m6a27pobu2m\nubWLprZumo52sa2hldd3dp1wmmq8rExjYsEHewyxjcIHG4mBG4+ciKaZBlLpi8ioMzOKcrMoys1i\nemnBkON7+/o52N59fCNx/G9bbCNxbHlHQytNrV109Q6+F1GUG4ltEIKNw7ENxfiCbErysyjJy2Zc\nXlZwP4txeVkp/30Hlb6IJJ1IZgblRbmUFw39a2buTnt3H82t3TS2dsU2CsHGIbZHEduLeK+pjdpd\nhzjY3s2prj5TmBOhOC+L4mMbg/ysYDn7+P2SvNhB8tiYbEryssjPzhwTU08qfREZ08yMgpwIBTmR\nU04xHdPb18+Rzl5aOno43N7N4Y4ejnT0cLg9dmvp6OFwRzctwf2t9a3B+m56+k6+tYhkWNwG4oON\nQfyeRHGwd1Ecv/HIyzqrl+RW6YtIWolkZjChIJsJBdnA0FNNx7g7HT19H2wYgg3BsfuHO2LrW9pj\nG42Go7EvyrW093C0q/eUr31s7+Kyc8fz/dvnDvOf8NRU+iIiCTAz8rMj5GdHOKck77Sem+jexaTi\noaezhkulLyIyys5072I0pPZhahEROYFKX0Qkjaj0RUTSiEpfRCSNqPRFRNKISl9EJI2o9EVE0ohK\nX0QkjZif6spDITCzRmD3MF6iFGgaoTgjSblOj3KdHuU6PamY61x3LxtqUNKV/nCZWa27V4edYyDl\nOj3KdXqU6/Skcy5N74iIpBGVvohIGknF0n8w7AAnoVynR7lOj3KdnrTNlXJz+iIicnKp+ElfRERO\nQqUvIpJGUqb0zexHZtZgZuvDznKMmU01s5fMbKOZbTCzL4edCcDMcs3sTTN7O8j1V2FnimdmmWb2\nlpn9R9hZjjGzXWb2rpmtM7PasPMcY2YlZrbMzDab2SYzWxh2JgAzuzD4d3XsdsTM/jgJcn0l+G9+\nvZk9Zmaj/1NVCTCzLweZNoy2A2OzAAADRUlEQVT2v6eUmdM3s6uAVuARd68KOw+AmU0CJrn7WjMr\nAtYAn3L3jSHnMqDA3VvNLAt4Ffiyu78eZq5jzOyrQDUwzt0/GXYeiJU+UO3uSfWFHjP7CfBbd3/I\nzLKBfHc/HHaueGaWCewFFrj7cL54Odwck4n9tz7H3TvM7AngGXf/cViZglxVwOPAfKAbeBb4grtv\nH433S5lP+u7+CnAw7Bzx3H2/u68N7h8FNgGTw00FHtMaLGYFt6TY+pvZFOB64KGwsyQ7MysGrgIe\nBnD37mQr/MC1wI4wCz9OBMgzswiQD+wLOQ/AbOANd293915gJfBfR+vNUqb0k52ZTQfmAm+EmyQm\nmEJZBzQAz7t7UuQCvgv8D6A/7CADOPCcma0xs3vCDhOYATQC/xpMhz1kZuH+AOvgbgMeCzuEu+8F\n/g54H9gPtLj7c+GmAmA9cKWZTTSzfOB3gamj9WYq/bPAzAqBp4A/dvcjYecBcPc+d78UmALMD3Yx\nQ2VmnwQa3H1N2FkG8TvufhlwHfClYDoxbBHgMuD/uftcoA34WriRThRMOd0APJkEWcYDNxLbWJ4D\nFJjZ58JNBe6+Cfhb4DliUzvrgL7Rej+V/igL5syfAn7m7r8IO89AwXTAS0BN2FmAjwE3BPPnjwPX\nmNm/hRspJviUiLs3AL8kNv8atjqgLm4vbRmxjUAyuQ5Y6+71YQcBFgHvuXuju/cAvwCuCDkTAO7+\nsLvPc/ergEPA1tF6L5X+KAoOmD4MbHL3fwg7zzFmVmZmJcH9PGAxsDncVODuf+ruU9x9OrEpgRfd\nPfRPYmZWEByIJ5g+WUJslzxU7n4A2GNmFwarrgVCPUlgELeTBFM7gfeBj5pZfvD/5rXEjrOFzszK\ng7/TiM3nPzpa7xUZrRc+28zsMeDjQKmZ1QHfcPeHw03Fx4A7gHeD+XOAP3P3Z0LMBDAJ+ElwVkUG\n8IS7J83pkUmoAvhlrCeIAI+6+7PhRjruj4CfBdMoO4E/CDnPccEGcjFwb9hZANz9DTNbBqwFeoG3\nSJ7LMTxlZhOBHuBLo3lAPmVO2RQRkaFpekdEJI2o9EVE0ohKX0Qkjaj0RUTSiEpfRCSNqPRFRNKI\nSl9EJI38f2z/x1WULsODAAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oaa4ModGKN4c",
        "colab_type": "text"
      },
      "source": [
        "##### 例 14.2"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "87a-GPzLKK62",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "X = [[0, 2], [0, 0], [1, 0], [5, 0], [5, 2]]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "NoacPJOONbqE",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 107
        },
        "outputId": "70147d21-d14d-416c-ab26-80b3f23793a2"
      },
      "source": [
        "np.asarray(X)"
      ],
      "execution_count": 208,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[0, 2],\n",
              "       [0, 0],\n",
              "       [1, 0],\n",
              "       [5, 0],\n",
              "       [5, 2]])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 208
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "w5CrPk68I9B9",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "m = MyKmeans(2, 100)\n",
        "points_set, centers = m.fit(np.asarray(X))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "THUOLIKiKkLc",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 53
        },
        "outputId": "693794ef-67b6-4bd4-e1bb-3d05facd10f1"
      },
      "source": [
        "points_set"
      ],
      "execution_count": 210,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{0: [array([5, 0]), array([5, 2])],\n",
              " 1: [array([0, 2]), array([0, 0]), array([1, 0])]}"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 210
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1TqaAPnnKrkn",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 53
        },
        "outputId": "7bfe9b28-4cda-4a20-ca99-112373a4313c"
      },
      "source": [
        "centers"
      ],
      "execution_count": 211,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[5, 1],\n",
              "       [0, 0]])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 211
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "7f_Jv2EFLmms",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "kmeans = KMeans(n_clusters=2, max_iter=100).fit(np.asarray(X))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "S5oVNBQdL-sl",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "outputId": "d04fd98e-8f47-4d8b-cf79-da6a19157843"
      },
      "source": [
        "kmeans.labels_"
      ],
      "execution_count": 213,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([0, 0, 0, 1, 1], dtype=int32)"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 213
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MG_sSMnHMU_r",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 53
        },
        "outputId": "9c4393a2-3f9e-492e-bd10-98d48ee6495c"
      },
      "source": [
        "kmeans.cluster_centers_"
      ],
      "execution_count": 214,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[0.33333333, 0.66666667],\n",
              "       [5.        , 1.        ]])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 214
        }
      ]
    }
  ]
}